import commonConstants from "@/common/commonConstants";
import commonMethod from "@/common/commonMethod";
import { Cartesian3 ,Math as cesiumMath, Color} from "cesium";

class InfluenceSource{
    constructor(){
        this.InfluenceMap = new Map();
    }


    /**
     * 发现影响体，其实就是工厂
     * @param  influenceType 
     * @param  options 
     */
    detectInfluence(influenceType,options){
        let influence = undefined;
        if(influenceType == commonConstants.influenceType.strong_wind){
            influence = new StrongWindInfluence(options)
        }else if (influenceType == commonConstants.influenceType.vortex) {
            influence = new VortexInfluence(options);
        }

        if(influence){
            this.addInfluence(influence);
        }
        return influence;
    }

    addInfluence(Influence){
        const _this = this;
        if(!_this.InfluenceMap.has(Influence.getID())){
            _this.InfluenceMap.set(Influence.getID(),Influence);
        }
    }

    removeInfluences(ifs){
        if(ifs){
            ifs.forEach(i => this.removeInfluence(i))
        }
    }

    removeInfluence(Influence){
        const InfluenceId = Influence.getID();
        if(this.InfluenceMap.has(InfluenceId)){
           const inf =  this.InfluenceMap.get(InfluenceId);
            inf.destory();
            this.InfluenceMap.delete(InfluenceId)   
        }
    }

    getInfluenceById(InfluenceId){
        return this.InfluenceMap.get(InfluenceId);
    }

    getAllInfluence(){
        const arrray = [];
        for (const key of this.InfluenceMap.keys()) {
            arrray.push(this.InfluenceMap.get(key))
        }
        return arrray;
    }
}


/**
 * 影响体，范围就用圆形范围，方便计算
 */
class Influence{
    constructor(){
        this.influenceId  = commonMethod.creatUUID();
        this.influenceName = "未命名";
        //影响中心点
        this.influenceCenter = undefined;
        this.influenceCenterString = ""; //用以显示
        //影响半径，单位 m
        this.influenceRaill = 1000

        //对于影响的描述
        this.influenceDescription = ""
        this.entity = undefined;
        this.className = "Influence"

         //影响因素，结果存储，以百分比表示
         this.influenceField = new Map();
         //源数据
         this.sourceField = new Map();

         this.v = undefined;
    }

    /**
     * 创建entity
     * @param v 
     */
    renderRange(v){
        if (!this.entity) {
            this.v = v;
            this.entity = v.entities.add({
                id: this.influenceId,
                name: this.influenceName,
                position: this.influenceCenter,
                ellipse: {
                semiMinorAxis: this.influenceRaill,
                semiMajorAxis: this.influenceRaill,
                height: 0,
                material: Color.BLUE.withAlpha(0.5),
                outline: true, // height must be set for outlines to display
                outlineColor:Color.BLACK.withAlpha(0.8)
                }
            })
        }
        return this.entity;
    }

    getEntity(){
        return this.entity;
    }

    getID(){
        return this.influenceId;
    }

    /**
     * 设置中心位置
     */
    setInfluenceCenter(center){
        this.influenceCenter = center
        const p = commonMethod.convertC3ToPosition(center);
        this.influenceCenterString = p.longitude.toFixed(4)+","+p.latitude.toFixed(4)

        //改变现在存在的实体
        if (this.entity) {
            this.entity.position = center;
        }
    }

    /**
     * 判断兵力是否被影响的条件
     * @returns 是否满足条件
     */
    condition(troop,t){
        if(troop){
             //具体的算法
            const des = Cartesian3.distance(troop.getEntity().position.getValue(t,new Cartesian3()),this.influenceCenter);
            if (des <= this.influenceRaill) {
               return true;
           }
        }
        return false;
    }

     /**
     * 处理影响，就是对影响的监听部署到时钟上
     * @param s
     */
     handleInfluence(s,t){
        const troopManager = s.getTroopManager();
        const troops = troopManager.getAllTroops();
        troops.forEach(element => {
            const bool = this.condition(element,t)
            if (bool) {
                if(!this.sourceField.has(element)){
                    this.sourceField.set(element,element.heading);
                    element.heading = this.influenceField.get("heading")
                }
            }else{
                if (this.sourceField.has(element)) {
                    element.heading = this.sourceField.get(element);
                    this.sourceField.delete(element);
                } 
            }
        });
    }

    destory(){
        if (this.entity) {
            this.v.entities.remove(this.entity)
        }
    }

}


/**
 * 强风影响体
 */
class StrongWindInfluence extends Influence{
    
    constructor(options){
        super();
        if (options) {
            this.handleOptions(options)
        }
        this.influenceType = commonConstants.influenceType.strong_wind;
        this.influenceField.set("speed",this._costAlgorithm())
    }

    /**
     * 处理生成影响体的数据
     * @param options 
     */
    handleOptions(options){
        if(options){
            if (options["influenceId"]) {
                this.influenceId = options["influenceId"]
            }
            if (options["influenceName"]) {
                this.influenceName = options["influenceName"]
            }
            if (options["influenceCenter"]) {
               this.setInfluenceCenter(options["influenceCenter"])
            }
            if (options["influenceCenterString"]) {
                this.influenceCenterString = options["influenceCenterString"]
            }
            if (options["influenceRaill"]) {
                this.influenceRaill = options["influenceRaill"]
            }
            if (options["influenceDescription"]) {
                this.influenceDescription = options["influenceDescription"]
            }
        }
    }

    _costAlgorithm(){
        return 1;
    }

}


/**
 * 旋涡影响体
 */
class VortexInfluence extends Influence{
    
    constructor(options){
        super();
        if (options) {
            this.handleOptions(options)
        }

        this.influenceType = commonConstants.influenceType.vortex;
        this.influenceField.set("heading",this._costAlgorithm())
    }

    /**
     * 影响的具体算法
     */
    _costAlgorithm(){
        //降低速度，为原来的 80%
        return cesiumMath.toRadians(90);
    }

    /**
     * 处理生成影响体的数据
     * @param options 
     */
    handleOptions(options){
        if(options){
            if (options["influenceId"]) {
                this.influenceId = options["influenceId"]
            }
            if (options["influenceName"]) {
                this.influenceName = options["influenceName"]
            }
            if (options["influenceCenter"]) {
                this.setInfluenceCenter(options["influenceCenter"])
            }
            if (options["influenceCenterString"]) {
                this.influenceCenterString = options["influenceCenterString"]
            }
            if (options["influenceRaill"]) {
                this.influenceRaill = options["influenceRaill"]
            }
            if (options["influenceDescription"]) {
                this.influenceDescription = options["influenceDescription"]
            }
        }
    }
}

export default InfluenceSource;